package cn.virens.common.spring.retry.annotations.handler;

import cn.virens.common.spring.annotations.VirAbstractMethodInterceptor;
import cn.virens.common.spring.retry.VirRetryException;
import cn.virens.common.utils.Assert;
import org.aopalliance.intercept.MethodInvocation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.retry.RetryException;

public class VirRetryMethodInterceptor extends VirAbstractMethodInterceptor {
    protected final Logger logger = LoggerFactory.getLogger(getClass());

    public VirRetryMethodInterceptor(VirRetryAnnotationSource annotationSource) {
        this.setAnnotationSource(Assert.isNull(annotationSource));
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
        int nowCount = 0;

        Exception exception = null;
        while (nowCount++ < getRetryCount(invocation)) {
            try {
                return invocation.proceed();
            } catch (RetryException ex) {
                exception = ex;
            } catch (VirRetryException ex) {
                exception = ex;
            }
        }

        throw exception;
    }

    private Integer getRetryCount(MethodInvocation invocation) {
        return findAnnotationAttributes(invocation).getNumber("value");
    }
}
